if (!Array.prototype.find) {
    Array.prototype.find = function (callback: any, thisArg: any) {
        if (this == null) {
            throw new TypeError("Array.prototype.find called on null or undefined");
        }
        if (typeof callback !== "function") {
            throw new TypeError(callback + " is not a function");
        }

        const O = Object(this);
        const len = O.length >>> 0;
        let T;
        if (arguments.length > 1) {
            T = thisArg;
        }

        for (let i = 0; i < len; i++) {
            if (i in O) {
                const value = O[i];
                if (callback.call(T, value, i, O)) {
                    return value;
                }
            }
        }
        return undefined;
    };
}

if (!Array.prototype.findIndex) {
    Array.prototype.findIndex = function (callback, thisArg) {
        if (this == null) {
            throw new TypeError("Array.prototype.findIndex called on null or undefined");
        }
        if (typeof callback !== "function") {
            throw new TypeError(callback + " is not a function");
        }

        const O = Object(this);
        const len = O.length >>> 0;
        let T;
        if (arguments.length > 1) {
            T = thisArg;
        }

        for (let i = 0; i < len; i++) {
            if (i in O) {
                const value = O[i];
                if (callback.call(T, value, i, O)) {
                    return i;
                }
            }
        }
        return -1;
    };
}

if (!Element.prototype.matches) Element.prototype.matches = (Element.prototype as any).msMatchesSelector || (Element.prototype as any).webkitMatchesSelector;

if (!Element.prototype.closest)
    Element.prototype.closest = function (s: any) {
        var el: Element | null = this;
        if (!document.documentElement.contains(el)) return null;
        do {
            if (el && el.matches(s)) return el;
            el = el ? el.parentElement : null;
        } while (el !== null);
        return null;
    };